'''
Created on 27/02/2009

@author: eh01
'''
from dao.messageDAO import MessageDAO
from domain.node import Node
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.runtime import DeadlineExceededError
from logindecorator import loginRequired
from requesthandler.requesthandlerconst import HTTP_HEADER_CONTENT_TYPE, \
    XML_CONTENT_TYPE, HTTP_HEADER_LOCATION
from exception.validationexception import ValidationException
from factory import messageFactory
from dao.nodeDAO import NodeDAO
import logging
import xmlHelper

class NodeRequestHandler(webapp.RequestHandler):
    @loginRequired
    def get(self, node_id):
        """return all message ids for all messages for node with id = node_id"""
        
        # wait request parameter determines if we are going to repeatedly check the 
        # memcache for new messages for the nodes
        wait = False
        if self.request.get("wait") == "true":
            wait = True
        logging.info("request made with node id = " + node_id + " with wait = " + str(wait))
        
        # update the last connected information
        nodeDAO = NodeDAO()
        node = None
        try:
            node = nodeDAO.findByNodeId(node_id)
        except IndexError:
            node = None

        if node:
            # By saving the object, the timestamp is updated to the time it was saved
            nodeDAO.save(node)
        else:
            # create new node entry if one doesn't already exists
            node = Node()
            node.id = int(node_id)
            nodeDAO.save(node)
                           
        # query for message
        messageDAO = MessageDAO();
        messages = messageDAO.findByNodeId(node_id)

        if messages:
            logging.info("messages for node id = " + node_id + " found")
            # if there are messages, then write messages to response
            self.response.clear()
            self.response.headers[HTTP_HEADER_CONTENT_TYPE] = XML_CONTENT_TYPE        
            self.response.out.write(xmlHelper.getMessagesIdsXML(messages))
            logging.info("here at the end")
        elif wait:
            # if no messages, then check memcache until result is returned
            try:
                messages = messageDAO.findByNodeIdMemcacheOnlyRepeatedly(node_id)
                logging.info("messages for node id = " + node_id + " found")
                # when result is returned, write messages to response
                self.response.headers[HTTP_HEADER_CONTENT_TYPE] = XML_CONTENT_TYPE        
                self.response.out.write(xmlHelper.getMessagesIdsXML(messages))                
            except DeadlineExceededError:
                # if the deadline is exceeding (this won't happen in the dev environement,
                # then return a 200 code and a empty message list
                logging.info("No messages found for node id = " + node_id) 
                self.response.clear()
                self.response.set_status(200)
                self.response.headers[HTTP_HEADER_CONTENT_TYPE] = XML_CONTENT_TYPE
                self.response.out.write(xmlHelper.getMessagesIdsXML(messages))
        else:
            logging.info("No messages found for node id = " + node_id)            
            # if no messages found, then write a empty message list to response
            self.response.headers[HTTP_HEADER_CONTENT_TYPE] = XML_CONTENT_TYPE        
            self.response.out.write(xmlHelper.getMessagesIdsXML(messages))
      
    @loginRequired
    def delete(self):
        """undefined"""
    @loginRequired
    def post(self):
        """undefined"""
    @loginRequired    
    def put(self, node_id):
        """creates a message for node with id = node_id and returns the message id"""
        try:
            message = messageFactory.createMessage(self.request, int(node_id))
            messageDAO = MessageDAO();
            messageDAO.save(message)        
            self.response.headers[HTTP_HEADER_CONTENT_TYPE] = XML_CONTENT_TYPE
            self.response.out.write(xmlHelper.getMessageIdXML(message))
            self.response.set_status(302)
            self.response.headers[HTTP_HEADER_LOCATION] = self.request.url + "/" + str(message.key().id())
        except ValidationException, e:
            self.response.clear()
            # if an attempt to add a message for a disconnected node, return 404
            self.response.set_status(404, e.message)
    
class MessageRequestHandler(webapp.RequestHandler):
    @loginRequired
    def get(self, node_id, message_id):
        """returns the message for node_id and message_id"""
        messageDAO = MessageDAO();
        message = messageDAO.findById(int(message_id))
        if message:
            self.response.headers[HTTP_HEADER_CONTENT_TYPE] = message.contentType
            self.response.out.write(xmlHelper.getMessageXML(message))
        else:
            self.response.set_status(404)
    @loginRequired
    def delete(self, node_id, message_id):
        """deletes the message with message_id and node_id"""
        messageDAO = MessageDAO();
        message = messageDAO.findById(int(message_id))
        if message:
            messageDAO.remove(message)
        else:
            # 403 if an attempt to delete a message that doesn't exist
            self.response.set_status(403, "Message does not exist")
    @loginRequired
    def post(self):
        """undefined"""
    @loginRequired            
    def put(self, node_id, message_id):
        """updates the message with message_id and node_id"""
        messageDAO = MessageDAO();
        message = messageDAO.findById(int(message_id))
        if message:
            message.body = self.request.body
            message = messageFactory.updateMessage(self.request, int(node_id), message)
            messageDAO.save(message)
            self.response.clear()
            self.response.headers[HTTP_HEADER_CONTENT_TYPE] = XML_CONTENT_TYPE
            self.response.out.write(xmlHelper.getMessageIdXML(message))
        else:
            # 403 if an attempt to update a message that doesn't exist
            self.response.set_status(403, "Message does not exist")
        
application = webapp.WSGIApplication([(r'/node/(.*)/(.*)', MessageRequestHandler),
                                      (r'/node/(.*)', NodeRequestHandler)],
                                     debug=True)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()        